//Copyright (c) 2012 The cwkshell Authors. All rights reserved. 
// Use of this source code is governed by a BSD-style license that can be 
// found in the LICENSE file. 
#ifndef CUC_CWKSHELL_BROWSER_FILE_SELECT_HELPER_H_ 
#define  CUC_CWKSHELL_BROWSER_FILE_SELECT_HELPER_H_ 
#include <map>
#include <vector>

#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "net/base/directory_lister.h"
#include "ui/shell_dialogs/select_file_dialog.h"
namespace content{
	class WebContents;
	struct FileChooserParams;
	class RenderViewHost;
}
namespace cuc{ 
	namespace shell{ 
		class FileSelectHelper:
			public base::RefCountedThreadSafe<FileSelectHelper>,
			public ui::SelectFileDialog::Listener,
			public content::NotificationObserver{
		public:
			~FileSelectHelper();
			static void RunFileChooser( content::WebContents* web_contents, 
				const content::FileChooserParams& params );
		private:
			friend class base::RefCountedThreadSafe<FileSelectHelper>;
			explicit FileSelectHelper();


			// Utility class which can listen for directory lister events and relay
			// them to the main object with the correct tracking id.
			class DirectoryListerDispatchDelegate
				: public net::DirectoryLister::DirectoryListerDelegate {
			public:
				DirectoryListerDispatchDelegate(FileSelectHelper* parent, int id)
					: parent_(parent),
					id_(id) {}
				virtual ~DirectoryListerDispatchDelegate() {}
				virtual void OnListFile(
					const net::DirectoryLister::DirectoryListerData& data) OVERRIDE;
				virtual void OnListDone(int error) OVERRIDE;
			private:
				// This FileSelectHelper owns this object.
				FileSelectHelper* parent_;
				int id_;

				DISALLOW_COPY_AND_ASSIGN(DirectoryListerDispatchDelegate);
			};

			void StartNewEnumeration( const base::FilePath& path,
				const int request_id, 
				content::RenderViewHost* render_view_host);
			// Cleans up and releases this instance. This must be called after the last
			// callback is received from the enumeration code.
			void EnumerateDirectoryEnd();


			void RunFileChooser(content::RenderViewHost* render_view_host,
				content::WebContents* tab_contents,
				const content::FileChooserParams& params);
			void RunFileChooserOnFileThread(
				const content::FileChooserParams& params);
			void RunFileChooserOnUIThread(
				const content::FileChooserParams& params);

			// Cleans up and releases this instance. This must be called after the last
			// callback is received from the file chooser dialog.
			void RunFileChooserEnd();

			// SelectFileDialog::Listener overrides.
			virtual void FileSelected(
				const base::FilePath& path, int index, void* params) OVERRIDE;
			virtual void FileSelectedWithExtraInfo(
				const ui::SelectedFileInfo& file,
				int index,
				void* params) OVERRIDE;
			virtual void MultiFilesSelected(const std::vector<base::FilePath>& files,
				void* params) OVERRIDE;
			virtual void MultiFilesSelectedWithExtraInfo(
				const std::vector<ui::SelectedFileInfo>& files,
				void* params) OVERRIDE;
			virtual void FileSelectionCanceled(void* params) OVERRIDE;

			// content::NotificationObserver overrides.
			virtual void Observe(int type,
				const content::NotificationSource& source,
				const content::NotificationDetails& details) OVERRIDE;


			// Callbacks from directory enumeration.
			virtual void OnListFile(
				int id,
				const net::DirectoryLister::DirectoryListerData& data);
			virtual void OnListDone(int id, int error);

			

			static scoped_ptr<ui::SelectFileDialog::FileTypeInfo>
				GetFileTypesFromAcceptType(const std::vector<string16>& accept_types);

			static bool IsAcceptTypeValid( std::string accept_type );

			// The RenderViewHost and WebContents for the page showing a file dialog
			// (may only be one such dialog).
			content::RenderViewHost* render_view_host_;
			content::WebContents* web_contents_;

			// Dialog box used for choosing files to upload from file form fields.
			scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
			scoped_ptr<ui::SelectFileDialog::FileTypeInfo> select_file_types_;

			// The type of file dialog last shown.
			ui::SelectFileDialog::Type dialog_type_;

			// Maintain a list of active directory enumerations.  These could come from
			// the file select dialog or from drag-and-drop of directories, so there could
			// be more than one going on at a time.
			struct ActiveDirectoryEnumeration;
			std::map<int, ActiveDirectoryEnumeration*> directory_enumerations_;

			// Registrar for notifications regarding our RenderViewHost.
			content::NotificationRegistrar notification_registrar_;

			DISALLOW_COPY_AND_ASSIGN(FileSelectHelper);


		};
	} //namespace shell 
} //namespace cuc 
#endif //CUC_CWKSHELL_BROWSER_FILE_SELECT_HELPER_H_ 
